package it.ap.sa.acqua.dao.impl;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StopWatch;

import it.ap.sa.acqua.dao.beans.SearchPlantFilter;
import it.ap.sa.acqua.dao.model.TPlant;
import it.ap.sa.core.dao.util.AbstractGenericEntityDao;
import it.ap.sa.core.utils.ListUtils;
import it.ap.sa.core.utils.LogUtil;
/**
 * @author Alessandro Paolillo
 */
@Repository
public class TPlantDao  extends AbstractGenericEntityDao<TPlant>{

	/**
	 * logger
	 */
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	/**
	 * @author Alessandro Paolillo
	 */
	@Transactional
	public TPlant findByPk(long id) throws Exception{
		try{
			String  hql     = "from " + TPlant.class.getName() + " where id = :id";
			Session session = this.getSessionFactory().getCurrentSession();
			Query   query   = session.createQuery(hql);

			query.setLong("id", id);

			return (TPlant)query.uniqueResult();
		}catch(Exception e){
			if(logger.isDebugEnabled())
				logger.debug("Error in findByPk", e);
			throw e;
		}
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public List<TPlant> findByPks(List<Long> ids) throws Exception{
		try{
			String  hql     = "from " + TPlant.class.getName() + " where id in (:ids)";
			Session session = this.getSessionFactory().getCurrentSession();
			Query   query   = session.createQuery(hql);

			query.setParameterList("ids", ids);

			return query.list();
		}catch(Exception e){
			if(logger.isDebugEnabled())
				logger.debug("Error in findByPks", e);
			throw e;
		}
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	public List<TPlant> getPlants() throws Exception{
		try{
			String  hql     = "from " + TPlant.class.getName();
			Session session = this.getSessionFactory().getCurrentSession();
			Query   query   = session.createQuery(hql);

			return query.list();
		}catch(Exception e){
			if(logger.isDebugEnabled())
				logger.debug("Error in getAcquari", e);
			throw e;
		}
	}
	/**
	 * @author Alessandro Paolillo
	 * @param {@link TPlant} tPlant
	 * @throws Exception
	 */
	@Transactional
	public TPlant saveOrUpdate(TPlant tPlant) throws Exception {

		String    idLog     = "saveOrUpdate";
		StopWatch stopWatch = LogUtil.startStopWatch(idLog);
		logger.info(idLog);
		try {
			saveEntity(tPlant);
		} catch (Exception ex) {

			logger.error("Si è verificato un errore in saveOrUpdate: " + ex.getMessage() , ex);
			throw(ex);
		} finally{

			logger.info(LogUtil.endStopWatch(stopWatch));
		}
		return tPlant;
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	public List<TPlant> searchPlant( SearchPlantFilter searchPlantFilter) throws Exception{
		
		Session session = this.getSessionFactory().getCurrentSession();
		try{
			
			String  hql     = "from " + TPlant.class.getName()+" ";
			if (searchPlantFilter!=null) {
				
				/** Set Filter **/	
				boolean isFirst = true;
				if ( searchPlantFilter.getScientificName()!=null && !searchPlantFilter.getScientificName().equals("") ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" scientific_name like :scientificName ";
					isFirst = false;
				}
				if ( searchPlantFilter.getId()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" id = :id ";
					isFirst = false;
				}
				if ( searchPlantFilter.getPhMax()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" ph_max <= :phMax ";
					isFirst = false;
				}
				if ( searchPlantFilter.getPhMin()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" ph_min >= :phMin ";
					isFirst = false;
				}
				if ( searchPlantFilter.getKhMax()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" kh_max <= :khMax ";
					isFirst = false;
				}
				if ( searchPlantFilter.getKhMin()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" kh_min >= :khMin ";
					isFirst = false;
				}	
				if ( searchPlantFilter.getGhMax()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" gh_max <= :ghMax ";
					isFirst = false;
				}
				if ( searchPlantFilter.getGhMin()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" gh_min >= :ghMin ";
					isFirst = false;
				}	
				if ( searchPlantFilter.getTemperatureMax()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" temperature_max <= :temperatureMax ";
					isFirst = false;
				}
				if ( searchPlantFilter.getTemperatureMin()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" temperature_min >= :temperatureMin ";
					isFirst = false;
				}	
				
				if ( searchPlantFilter.getExcludePlant()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" id not in ( :excludePlant ) ";
					isFirst = false;
				}	
			}
			Query   query   = session.createQuery(hql);
			
			if (searchPlantFilter!=null) {
				
				/** Set parameter **/
				if ( searchPlantFilter.getScientificName()!=null && !searchPlantFilter.getScientificName().equals("") )
					query.setString("scientificName", "%"+searchPlantFilter.getScientificName()+"%");
				if ( searchPlantFilter.getId()!=null  )
					query.setLong("id", searchPlantFilter.getId());
				
				if ( searchPlantFilter.getPhMax()!=null )
					query.setDouble("phMax", searchPlantFilter.getPhMax());
				if ( searchPlantFilter.getPhMin()!=null )
					query.setDouble("phMin", searchPlantFilter.getPhMin());
				if ( searchPlantFilter.getKhMax()!=null )
					query.setDouble("khMax", searchPlantFilter.getKhMax());
				if ( searchPlantFilter.getKhMin()!=null )
					query.setDouble("khMin", searchPlantFilter.getKhMin());
				if ( searchPlantFilter.getGhMax()!=null )
					query.setDouble("ghMax", searchPlantFilter.getGhMax());
				if ( searchPlantFilter.getGhMin()!=null )
					query.setDouble("ghMin", searchPlantFilter.getGhMin());
				if ( searchPlantFilter.getTemperatureMax()!=null )
					query.setDouble("temperatureMax", searchPlantFilter.getTemperatureMax());
				if ( searchPlantFilter.getTemperatureMin()!=null )
					query.setDouble("temperatureMin", searchPlantFilter.getTemperatureMin());
				
				if ( searchPlantFilter.getExcludePlant()!=null )
					query.setParameterList("excludePlant", searchPlantFilter.getExcludePlant());
				
				/** Set paginator **/
				if ( searchPlantFilter.getiDisplayStart()!=-1 )
					query.setFirstResult( searchPlantFilter.getiDisplayStart() );
				if ( searchPlantFilter.getiDisplayLength()!=-1 )
					query.setMaxResults( searchPlantFilter.getiDisplayLength() );
			}
			return (List<TPlant>)query.list();
		}catch(Exception e){
			if(logger.isDebugEnabled())
				logger.debug("Error in searchPlant", e);
			throw e;
		}
	}
	
	/**
	 * @author Alessandro Paolillo
	 */
	public Long searchCountPlant( SearchPlantFilter filter) throws Exception{
		
		Session session = this.getSessionFactory().getCurrentSession();
		try{
			String  hql     = "from " + TPlant.class.getName()+" ";
			if (filter!=null) {
				
				/** Set Filter **/	
				boolean isFirst = true;
				if ( filter.getScientificName()!=null && !filter.getScientificName().equals("") ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" scientific_name like :scientificName ";
					isFirst = false;
				}
				if ( filter.getId()!=null ) {
					hql += ( isFirst ? "WHERE" : "AND" ) +" id = :id ";
					isFirst = false;
				}
			}
			Query   query   = session.createQuery(hql);
			if (filter!=null) {
				
				/** Set parameter **/
				if ( filter.getScientificName()!=null && !filter.getScientificName().equals("") )
					query.setString("scientificName", "%"+filter.getScientificName()+"%");
				if ( filter.getId()!=null  )
					query.setLong("id", filter.getId());
			}
			List<TPlant> list = (List<TPlant>)query.list();
			if(ListUtils.listIsNotEmpty(list))
				return new Long ( list.size() );
			else 
				return new Long( 0 );
		}catch(Exception e){
			if(logger.isDebugEnabled())
				logger.debug("Error in searchCountPlant", e);
			throw e;
		}
	}
}